package com.niuwa.p2p.service.impl.channel;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.niuwa.p2p.core.mvc.entity.PageBean;
import com.niuwa.p2p.core.utils.DictConstant;
import com.niuwa.p2p.core.utils.DictConstant.ChannelAuditStatus;
import com.niuwa.p2p.core.utils.DictConstant.ChlAuditAction;
import com.niuwa.p2p.core.utils.DictConstant.FlagStatus;
import com.niuwa.p2p.core.utils.DictConstant.LOAN_CORP_TYPE;
import com.niuwa.p2p.core.utils.StringUtil;
import com.niuwa.p2p.dao.channel.ChannelCustomerDao;
import com.niuwa.p2p.dao.channel.ChannelInfoDao;
import com.niuwa.p2p.dao.channel.CorpAuditLogDao;
import com.niuwa.p2p.dao.channel.CorpContactorDao;
import com.niuwa.p2p.dao.channel.CorpManagerDao;
import com.niuwa.p2p.dao.channel.CorpShareHolderDao;
import com.niuwa.p2p.dao.channel.CorporationDao;
import com.niuwa.p2p.dao.channel.ManagerRelativeCorpDao;
import com.niuwa.p2p.dao.channel.ShareHolderDao;
import com.niuwa.p2p.entity.PageQuery;
import com.niuwa.p2p.entity.channel.ChannelDetailInfo;
import com.niuwa.p2p.entity.channel.ChannelInfo;
import com.niuwa.p2p.entity.channel.CorpAuditLog;
import com.niuwa.p2p.entity.channel.CorpContactor;
import com.niuwa.p2p.entity.channel.CorpManager;
import com.niuwa.p2p.entity.channel.CorpShareHolder;
import com.niuwa.p2p.entity.channel.Corporation;
import com.niuwa.p2p.entity.channel.ManagerRelativeCorp;
import com.niuwa.p2p.entity.channel.ShareHolder;
import com.niuwa.p2p.exception.BusinessException;
import com.niuwa.p2p.service.channel.ChannelConstant;
import com.niuwa.p2p.service.channel.IChannelCustomerService;
import com.niuwa.p2p.service.sequence.ISequenceService;
import com.niuwa.p2p.vo.channel.AuditFrom;
import com.niuwa.p2p.vo.channel.ChannelAuditLogVo;
import com.niuwa.p2p.vo.channel.ChannelBasicInfoVo;
import com.niuwa.p2p.vo.channel.ChannelCustomerVo;

@Service
public class ChannelCustomerServiceImpl implements IChannelCustomerService {
	
    private final Logger logger = Logger.getLogger(ChannelCustomerServiceImpl.class);
    
    @Autowired
    private ChannelCustomerDao channelCustomerDao;

    @Autowired
    private ChannelInfoDao channelInfoDao;

    @Autowired
    private CorpAuditLogDao corpAuditLogDao;

    @Autowired
    private ShareHolderDao shareHolderDao;

    @Autowired
    private CorporationDao corporationDao;

    @Autowired
    private CorpShareHolderDao corpShareHolderDao;
    
    @Autowired
    private CorpManagerDao corpManagerDao;
    
    @Autowired
    private CorpContactorDao corpContactorDao;
    
    @Autowired
    private ManagerRelativeCorpDao managerRelativeCorpDao;

    @Autowired
    private ISequenceService sequenceService;
    
	/**
	 * 分页查询渠道客户集合
	 * 根据paramMap，选取需要的渠道客户集合 
	 * 
	 * @param paramMap 过滤得条件Map
	 * @return PageBean<ChannelCustomerVo> 渠道客户 分页信息集合
	 */
	@Override
	public PageBean<ChannelCustomerVo> search(Map<String, Object> paramMap) {

		assert paramMap.get(PageQuery.PAGEQUERY) != null;

		int totalCount = channelCustomerDao.count(paramMap);

		PageBean<ChannelCustomerVo> page = new PageBean<ChannelCustomerVo>(totalCount);

		// 设置当前页
		page.setPage(((PageQuery) paramMap.get(PageQuery.PAGEQUERY)).getPage());

		page.setRows(channelCustomerDao.selectChannelCustomerBySelective(paramMap));

		return page;
	}
	
	/**
	 * 提交审核
	 * @param channelCode 业务编号
	 * @param operatorId 操作员ID 
	 * @throws Exception
	 */
	public int updateToAuditChannel(String channelCode, long operatorId) throws Exception{
		int result = 0;
		// 取得渠道信息
		ChannelInfo channelInfo = channelInfoDao.selectByPrimaryKey(channelCode);
		// 不存在,抛出错误
		if (channelInfo == null) {
			throw new BusinessException("ChannelCustomerService.channelInfoIsNotExist");
		}
		// 取得企业信息
		Corporation corporation = corporationDao.selectByPrimaryKey(channelCode);
		// 不存在,抛出错误
		if (corporation == null) {
			throw new BusinessException("EnterpriseinfoMgService.corporationIsNotExist");
		}
		// 设置审核状态:审核中
		corporation.setAuditStatus(ChannelAuditStatus.AUDITING.getCode());
		// 更新渠道信息
		result = corporationDao.updateByPrimaryKeySelective(corporation);
		if(result != 1) {
			throw new BusinessException("ChannelCustomerService.failTOToAuditChannel");
		}
		return result;
	}

	/**
	 * 审核
	 * @param channelCode 业务编号
	 * @param auditFrom 渠道审核Form 
	 * @param operatorId 操作员ID
	 * @throws Exception
	 */
	public int updateAuditChannel(String channelCode, AuditFrom auditFrom, long operatorId) throws Exception{
		int result = 0;
		// 取得渠道信息
		ChannelInfo channelInfo = channelInfoDao.selectByPrimaryKey(channelCode);
		// 不存在,抛出错误
		if (channelInfo == null) {
			throw new BusinessException("ChannelCustomerService.channelInfoIsNotExist");
		}
		// 取得企业信息
		Corporation corporation = corporationDao.selectByPrimaryKey(channelCode);
		// 不存在,抛出错误
		if (corporation == null) {
			throw new BusinessException("EnterpriseinfoMgService.corporationIsNotExist");
		}	
		// 设置渠道审核类型
		if(ChlAuditAction.PASS.getCode().equals(auditFrom.getOperateType())) {
			corporation.setAuditStatus(ChannelAuditStatus.PASS.getCode());
			// 设定渠道核准金额
		    channelInfo.setApproveAmount(auditFrom.getApproveAmount().multiply(new BigDecimal(10000)));
			// 更新渠道信息 - 金额
			result = channelInfoDao.updateByPrimaryKeySelective(channelInfo);
			if(result != 1) {
				throw new BusinessException("ChannelCustomerService.failTOAuditChannel");
			}
		}else if(ChlAuditAction.RETURN.getCode().equals(auditFrom.getOperateType())) {
			corporation.setAuditStatus(ChannelAuditStatus.RETURN.getCode());
		}else if(ChlAuditAction.REJECT.getCode().equals(auditFrom.getOperateType())) {
			corporation.setAuditStatus(ChannelAuditStatus.REJECT.getCode());
		}			
		// 更新企业信息 - 审核状态
		result = corporationDao.updateByPrimaryKeySelective(corporation);
		if(result != 1) {
			throw new BusinessException("EnterpriseinfoMgService.failTOAuditcorporation");
		}
		// 添加渠道审核操作记录
		CorpAuditLog corpAuditLog = new CorpAuditLog();
		corpAuditLog.setCorpCode(channelCode);
		// 设定渠道审核类型
		corpAuditLog.setOperateType(auditFrom.getOperateType());
		corpAuditLog.setCreateTime(new Date());
		corpAuditLog.setOperator(operatorId);
		// 设定渠道审核理由
		corpAuditLog.setRemark(auditFrom.getRemark());
		result = corpAuditLogDao.insert(corpAuditLog);
		if(result != 1) {
			throw new BusinessException("ChannelCustomerService.failTOAddChannelAuditLog");
		}
		return result;
	}
	
	/**
	 * 启用
	 * @param channelCode 业务编号
	 * @param operatorId 操作员ID
	 * @throws Exception
	 */
	public int updateEnableChannel(String channelCode, long operatorId) throws Exception{
		int result = 0;
		// 取得渠道信息
		ChannelInfo channelInfo = channelInfoDao.selectByPrimaryKey(channelCode);
		// 不存在,抛出错误
		if (channelInfo == null) {
			throw new BusinessException("ChannelCustomerService.channelInfoIsNotExist");
		}
		// 取得企业信息
		Corporation corporation = corporationDao.selectByPrimaryKey(channelCode);
		// 不存在,抛出错误
		if (corporation == null) {
			throw new BusinessException("EnterpriseinfoMgService.corporationIsNotExist");
		}
		// 设置审核状态:材料录入
		corporation.setAuditStatus(ChannelAuditStatus.EDIT.getCode());
		// 更新渠道信息
		result = corporationDao.updateByPrimaryKeySelective(corporation);
		if(result != 1) {
			throw new BusinessException("ChannelCustomerService.failTOEnableChannel");
		}
		return result;
	}
	
	/**
	 * 分页查询渠道审核操作集合
	 * 根据paramMap，选取需要的渠道审核操作集合 
	 * 
	 * @param paramMap 过滤得条件Map
	 * @return PageBean<ChannelAuditLogVo> 渠道审核操作分页信息集合
	 */
	public PageBean<ChannelAuditLogVo> listAuditOperateRecord(Map<String, Object> paramMap){
		assert paramMap.get(PageQuery.PAGEQUERY) != null;

		int totalCount = channelCustomerDao.countChannelAuditOperateByChannelCodeSelective(paramMap);

		PageBean<ChannelAuditLogVo> page = new PageBean<ChannelAuditLogVo>(totalCount);

		// 设置当前页
		page.setPage(((PageQuery) paramMap.get(PageQuery.PAGEQUERY)).getPage());

		page.setRows(channelCustomerDao.selectChannelAuditOperateByChannelCodeSelective(paramMap));

		return page;
		
	}

    /*
     * 新增渠道
     * @param ChannelBasicInfoVo 
     * @return ChannelCode 渠道编号
     */
    public String addNewChannelCustomer(ChannelBasicInfoVo cbiv) throws Exception{

        long seq = sequenceService.getNextSequenceBySeqKey(DictConstant.ChannelIdType.QDYH.getCode());
        ChannelInfo ci = cbiv.getChannelInfo();
        Corporation corporation = cbiv.getCorporation();
        
        //转换金额
        cbiv.getChannelInfo().setApplyAmount(cbiv.getChannelInfo().getApplyAmount().multiply(new BigDecimal(10000)));
        cbiv.getCorporation().setRegAmount(cbiv.getCorporation().getRegAmount().multiply(new BigDecimal(10000)));
        List<ShareHolder> shareHolders = cbiv.getShareHolder();
        // 原始的corpShareHolder,需要进行转化...
        List<CorpShareHolder> corpShareHolders = cbiv.getCorpShareHolder();

        String channelCode = "QD" + String.format("%04d", seq);
        ci.setChannelCode(channelCode);
        ci.setCreateTime(new Date());       

        // 公司编号与渠道编号一致
        corporation.setCorpCode(channelCode);
        corporation.setCreateTime(new Date());
        corporation.setAuditStatus(ChannelAuditStatus.EDIT.getCode());
        corporation.setCorpType(LOAN_CORP_TYPE.CHANNEL.getCode());
        corporation.setDelFlag(FlagStatus.N.name());
        for (int i = 0; i < shareHolders.size(); i++) {
            // 判断类型
            long seq2 = sequenceService.getNextSequenceBySeqKey(DictConstant.ChannelIdType.GDXX.getCode());

            String shareHolderCode = channelCode + "S" + String.format("%03d", seq2);
            shareHolders.get(i).setShareholderCode(shareHolderCode);
            //covert regAmount
            BigDecimal regAmount = shareHolders.get(i).getRegAmount();
            if(regAmount != null){
                shareHolders.get(i).setRegAmount(regAmount.multiply(new BigDecimal(10000)));
            }
            corpShareHolders.get(i).setCorpCode(channelCode);
            corpShareHolders.get(i).setShareholderCode(shareHolderCode);
            
        }
        
        // 设置法人数据	XiangChaoLei
        CorpManager legalMan = cbiv.getLegalMan();
        long legalManSeq = sequenceService.getNextSequenceBySeqKey(DictConstant.ChannelIdType.JLXX.getCode());
        String legalManCode = channelCode + "M" + String.format("%03d", legalManSeq);
        legalMan.setManagerCode(legalManCode);
        legalMan.setCreateTime(new Date());
        ManagerRelativeCorp legalManRela = new ManagerRelativeCorp();
        legalManRela.setCorpCode(channelCode);
        legalManRela.setManagerCode(legalManCode);
        legalManRela.setManagerType("LEGAL_MAN");
        // 设置法人数据end
        
        // 设置总经理数据	XiangChaoLei
        CorpManager generalManager = cbiv.getGeneralManager();
        long generalManagerSeq = sequenceService.getNextSequenceBySeqKey(DictConstant.ChannelIdType.JLXX.getCode());
        String generalManagerCode = channelCode + "M" + String.format("%03d", generalManagerSeq);
        generalManager.setManagerCode(generalManagerCode);
        generalManager.setCreateTime(new Date());
        ManagerRelativeCorp generalManagerRela = new ManagerRelativeCorp();
        generalManagerRela.setCorpCode(channelCode);
        generalManagerRela.setManagerCode(generalManagerCode);
        generalManagerRela.setManagerType("GENERAL_MANAGER");
        // 设置总经理数据end

        // save all the data
        channelInfoDao.insert(ci);
        corporationDao.insert(corporation);
        for (int i = 0; i < shareHolders.size(); i++) {
            shareHolderDao.insert(shareHolders.get(i));
            corpShareHolderDao.insert(corpShareHolders.get(i));
        }
        
        // 保存法人及总经理数据		XiangChaoLei
        corpManagerDao.insert(legalMan);
        managerRelativeCorpDao.insert(legalManRela);
        corpManagerDao.insert(generalManager);
        managerRelativeCorpDao.insert(generalManagerRela);
        // 保存法人及总经理数据end
        
        // 保存联系人信息	XiangChaoLei
        for(int i = 0; i < cbiv.getCorpContactor().size(); i++){
        	CorpContactor corpContactor = cbiv.getCorpContactor().get(i);
        	corpContactor.setCorpCode(channelCode);
        	corpContactor.setCreateTeme(new Date());
        	corpContactorDao.insert(corpContactor);
        }
        // 保存联系人信息end
        
        return channelCode;
    }

    /**
  	 * 查询渠道信息
  	 * 包括基本信息，股东信息，法人信息，总经理信息
  	 *
  	 */
  	public ChannelDetailInfo getChannelInfo(String channelCode){
  		ChannelDetailInfo channelDetailInfo = new ChannelDetailInfo();
  		//规则理解，渠道id和公司id是一个意思
  		//取得渠道信息
  		ChannelInfo channelInfo = channelInfoDao.selectByPrimaryKey(channelCode);
  		String corpCode = channelInfo.getChannelCode();
  		//根据公司查找股东信息（通过中间表进行查询 p2p_corp_shareholder）
  		List<ShareHolder> shareHolderList = shareHolderDao.selectShareholderByCorpCodeForChannelDetail(corpCode);
  		channelDetailInfo.setChannelInfo(channelInfo);
  		channelDetailInfo.setShareHolderList(shareHolderList);
  		//查找公司法人信息和公司总经理信息（MANAGER_TYPE ：LEGAL_MAN（法人），GENERAL_MANAGER（总经理））
  		List<CorpManager> corpManagerList = corpManagerDao.selectPersonsInfoByCorpcode(corpCode);
  		for(CorpManager crpManager:corpManagerList){
  			String managerType = crpManager.getManagerType();
  			if(!StringUtil.isEmpty(managerType)&&managerType.equals(ChannelConstant.CORP_MANGERTYPE[0])){
  				List<CorpManager>  legpersonList = channelDetailInfo.getCorpLegalpersonList();
  				if(legpersonList==null){
  					legpersonList = new ArrayList<CorpManager>();
  				}
  				legpersonList.add(crpManager);
  				channelDetailInfo.setCorpLegalpersonList(legpersonList);
  			}
  			if(!StringUtil.isEmpty(managerType)&&managerType.equals(ChannelConstant.CORP_MANGERTYPE[1])){
  				List<CorpManager>  gengerMangerPersonList = channelDetailInfo.getCorpGeneralManagerList();
  				if(gengerMangerPersonList==null){
  					gengerMangerPersonList = new ArrayList<CorpManager>();
  				}
  				gengerMangerPersonList.add(crpManager);
  				channelDetailInfo.setCorpGeneralManagerList(gengerMangerPersonList);
  			}
  		}
  		return channelDetailInfo;
  	}
  	
  	
  	/*
  	 * 删除渠道Logo
  	 */
  	public int deleteChannelLogo(String channelCode){
  	  ChannelInfo channelInfo = channelInfoDao.selectByPrimaryKey(channelCode);
  	  channelInfo.setChannelLogo(null);
  	  int result = channelInfoDao.updateByPrimaryKey(channelInfo);
      if(result != 1) {
          throw new BusinessException("ChannelCustomerService.failTODeleteChannelLogo");
      }
  	  return result;
  	}
  	
	/**
	 * 取得渠道基本信息
	 * @param channelCode 业务编号
	 * @return ChannelBasicInfoVo 渠道基本信息
	 */
	public ChannelBasicInfoVo getChannelBasicInfo(String channelCode){		
		return channelCustomerDao.selectChannelBasicInfoByChannelCode(channelCode);	
	}

	/*
	 * 更新渠道基本信息
	 * 
	 */
    public int updateChannelCustomer(ChannelBasicInfoVo cbiv) throws Exception {

        int result = 0;
        ChannelBasicInfoVo oldCbiv = getChannelBasicInfo(cbiv.getChannelInfo().getChannelCode());
        
        String channelCode = oldCbiv.getChannelInfo().getChannelCode();

        //转换申请金额
        cbiv.getChannelInfo().setApplyAmount(cbiv.getChannelInfo().getApplyAmount().multiply(new BigDecimal(10000)));
        cbiv.getCorporation().setRegAmount(cbiv.getCorporation().getRegAmount().multiply(new BigDecimal(10000)));
        // 更新渠道基本信息
        result = channelInfoDao.updateByPrimaryKeySelective(cbiv.getChannelInfo());
        if(result != 1) {
            throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
        }
        //更新公司基本信息
        result = corporationDao.updateByPrimaryKeySelective(cbiv.getCorporation());
        if(result != 1) {
            throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
        }
        
        //更新股东信息
        List<ShareHolder> newShs = cbiv.getShareHolder();
        List<CorpShareHolder> newCsh = cbiv.getCorpShareHolder();
        
        List<ShareHolder> oldShs = oldCbiv.getShareHolder();
        List<CorpShareHolder> oldCsh = oldCbiv.getCorpShareHolder();
        
        HashMap<String,ShareHolder> shareHolderKeys = new HashMap<String,ShareHolder>();
        HashMap<String,CorpShareHolder> corpShareHolderKeys = new HashMap<String,CorpShareHolder>();

        for(int i = 0;i < oldShs.size();i++){
            shareHolderKeys.put(oldShs.get(i).getShareholderCode(), oldShs.get(i));
            corpShareHolderKeys.put(oldCsh.get(i).getShareholderCode(), oldCsh.get(i));
        }

        for(int i = 0; i < newShs.size();i++){
            
            BigDecimal regAmount = newShs.get(i).getRegAmount();
            if(regAmount != null){
                newShs.get(i).setRegAmount(regAmount.multiply(new BigDecimal(10000)));
            }
            
            if(shareHolderKeys.containsKey(newShs.get(i).getShareholderCode())){
                //update
                result = shareHolderDao.updateByPrimaryKey(newShs.get(i));
                if(result != 1) {
                    throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
                }
                
                newCsh.get(i).setShareholderCode(newShs.get(i).getShareholderCode());
                newCsh.get(i).setCorpCode(cbiv.getCorporation().getCorpCode());
                result = corpShareHolderDao.updateByPrimaryKey(newCsh.get(i));
                if (result != 1) {
                    throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
                }
                shareHolderKeys.remove(newShs.get(i).getShareholderCode());
                corpShareHolderKeys.remove(newShs.get(i).getShareholderCode());
            }else{
                //insert, 增加相应字段...
                long seq2 = sequenceService.getNextSequenceBySeqKey(DictConstant.ChannelIdType.GDXX.getCode());

                String shareHolderCode = channelCode + "S" + String.format("%03d", seq2);
                newShs.get(i).setShareholderCode(shareHolderCode);
                newCsh.get(i).setCorpCode(channelCode);
                newCsh.get(i).setShareholderCode(shareHolderCode);

                result = shareHolderDao.insert(newShs.get(i));
                if(result != 1) {
                    throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
                }
                result = corpShareHolderDao.insert(newCsh.get(i));
                
                if(result != 1) {
                    throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
                }
            }
            if(result != 1) {
                throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
            }
        }

        //delete all the delete info
        Iterator<Entry<String, ShareHolder>> iter = shareHolderKeys.entrySet().iterator();
        while (iter.hasNext()) {

            ShareHolder val = iter.next().getValue();
            result = shareHolderDao.deleteByPrimaryKey(val.getShareholderCode());
            if(result != 1) {
                throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
            }
        }
        Iterator<Entry<String, CorpShareHolder>> iter2 = corpShareHolderKeys.entrySet().iterator();
        while (iter2.hasNext()) {
            CorpShareHolder val = iter2.next().getValue();
            result = corpShareHolderDao.deleteByPrimaryKey(val);
            if(result != 1) {
                throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
            }
        }
        
        // 更新法人数据	XiangChaoLei
        CorpManager legalMan = cbiv.getLegalMan();
        legalMan.setManagerCode(oldCbiv.getLegalMan().getManagerCode());
        result = corpManagerDao.updateByPrimaryKey(legalMan);
        if(result != 1) {
            throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
        }
        // 更新法人数据end
        
        // 更新总经理数据	XiangChaoLei
        CorpManager generalManager = cbiv.getGeneralManager();
        generalManager.setManagerCode(oldCbiv.getGeneralManager().getManagerCode());
        result = corpManagerDao.updateByPrimaryKey(generalManager);
        if(result != 1) {
            throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
        }
        // 更新总经理数据end
        
        // 保存联系人信息	XiangChaoLei
        // 如果以前没有保存过
        if(oldCbiv.getCorpContactor().isEmpty()){
        	for(int i = 0; i < cbiv.getCorpContactor().size(); i++){
            	CorpContactor corpContactor = cbiv.getCorpContactor().get(i);
            	corpContactor.setCorpCode(channelCode);
            	corpContactor.setCreateTeme(new Date());
            	result = corpContactorDao.insert(corpContactor);
            	if(result != 1) {
                    throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
                }
            }
        }
        else{
        	for(int i = 0; i < cbiv.getCorpContactor().size(); i++){
            	CorpContactor corpContactor = cbiv.getCorpContactor().get(i);
            	result = corpContactorDao.updateByPrimaryKeySelective(corpContactor);
            	if(result != 1) {
                    throw new BusinessException("ChannelCustomerService.failTOUpdateBasicChannelInfo");
                }
            }
        }
        
        // 保存联系人信息end
        
        return result;
    }
}
